package org.chaos.sekiro.workorder.app.form.internal.dao

import org.chaos.sekiro.common.ktorm.AuditTable
import org.chaos.sekiro.workorder.app.form.internal.model.ComponentAbility
import org.chaos.sekiro.workorder.common.enumeration.ComponentAbilityCode
import org.ktorm.database.Database
import org.ktorm.dsl.and
import org.ktorm.dsl.eq
import org.ktorm.dsl.inList
import org.ktorm.entity.*
import org.ktorm.schema.boolean
import org.ktorm.schema.enum
import org.ktorm.schema.long
import org.ktorm.schema.varchar
import org.springframework.stereotype.Repository

object ComponentAbilities : AuditTable<ComponentAbility>("wo_component_abilities") {
    val id = long("id").primaryKey().bindTo { it.id }
    val userId = long("user_id").bindTo { it.userId }
    val code = enum<ComponentAbilityCode>("code").bindTo { it.code }
    val name = varchar("name").bindTo { it.name }
    val customCode = varchar("custom_code").bindTo { it.customCode }
    val deleted = boolean("deleted").bindTo { it.deleted }
}

val Database.componentAbilities get() = this.sequenceOf(ComponentAbilities)

@Repository
class ComponentAbilityDao(
    private val database: Database
) {

    fun findByUserIdAndDeleted(
        userId: Long,
        deleted: Boolean = false
    ): List<ComponentAbility> =
        database.componentAbilities.filter {
            (it.userId inList listOf(0L, userId)) and
                    (it.deleted eq deleted)
        }.sortedBy { it.id }.toList()

    fun findByUserIdAndIdInAndDeleted(
        userId: Long,
        ids: Collection<Long>,
        deleted: Boolean = false
    ): List<ComponentAbility> =
        database.componentAbilities.filter {
            (it.userId inList listOf(0L, userId)) and
                    (it.id inList ids) and
                    (it.deleted eq deleted)
        }.sortedBy { it.id }.toList()

    fun findByUserIdAndCodeAndCustomCodeAndDeleted(
        userId: Long,
        code: ComponentAbilityCode,
        customCode: String,
        deleted: Boolean = false
    ): ComponentAbility? =
        database.componentAbilities.find {
            (it.userId inList listOf(0L, userId)) and
                    (it.code eq code)  and
                    (it.customCode eq customCode) and
                    (it.deleted eq deleted)
        }
}